﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Silverlight.Testing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Threading;
using SilverlightClient.SLWcfGeebaService;
using AcceptnaceTests;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using SilverlightClient.Utils;
using System.ServiceModel;

namespace SilverlightTests
{
    [TestClass()]
    public class SilverlightClientTests : SilverlightTest
    {

        SilverlightClient.SLWcfGeebaService.SLServiceClient _server;
        Member _admin;
        User _user;
        Member _member;
        GThread _thread;
        GPost _post;
        List<GSubForum> _sfs;
        List<GThread> _threads;
        bool _addModRes;
        int _memberThreadCount;
        int _threadCount;
        string _currentTopic;

        public SilverlightClientTests()
        {
            //_server = new SLServiceClient();
            
            var address = new EndpointAddress("http://localhost:23620/SLService.svc");
            var binding = new PollingDuplexHttpBinding();
            _server = new SLServiceClient(binding, address);
        }

        #region TestingUtils

        /// <summary>
        ///Initialize() is called once during test execution before
        ///test methods in this test class are executed.
        ///</summary>
        [TestInitialize()]
        [Asynchronous]
        public void Initialize()
        {
            // entry as admin...
            User admin_user = null;
            bool is_entryCompleted = false;
            _server.entryCompleted +=
                (object sender, SilverlightClient.SLWcfGeebaService.entryCompletedEventArgs e) =>
                {
                    if (e.UserState == null || e.UserState.ToString() != "ADMIN_LOGIN") { return; }

                    admin_user = e.Result;
                    is_entryCompleted = true;
                };
            _server.entryAsync("ADMIN_LOGIN");
            EnqueueConditional(() => is_entryCompleted);
            // login as admin...
            bool is_loginCompleted = false;
            _server.loginCompleted +=
                    (object sender, SilverlightClient.SLWcfGeebaService.loginCompletedEventArgs e) =>
                    {
                        if (e.UserState == null || e.UserState.ToString() != "ADMIN_LOGIN") { return; }

                        _admin = e.Result;
                        is_loginCompleted = true;
                    };
            EnqueueCallback(() => 
                {
                    _server.loginAsync(admin_user, TestUtils.GetAdminUsername(), EncDec.Encrypt(TestUtils.GetAdminPassword(), EncDec.getServerKey()), "ADMIN_LOGIN");   
                });
            EnqueueConditional(() => is_loginCompleted);
            EnqueueCallback(() =>
            {
                if (_admin == null)
                {
                    throw new Exception("Error: Could not login as admin!");
                }
            });
            EnqueueTestComplete();
        }

        [TestCleanup()]
        [Asynchronous]
        public void Cleanup()
        {
            // logout...
            User user = null;
            bool is_logoutCompleted = false;
            _server.logoutCompleted +=
                    (object sender, SilverlightClient.SLWcfGeebaService.logoutCompletedEventArgs e) =>
                    {
                        user = e.Result;
                        is_logoutCompleted = true;
                    };
            EnqueueCallback(() => _server.logoutAsync(_admin.username));
            EnqueueConditional(() => is_logoutCompleted);

            EnqueueTestComplete();
        }

        #endregion

        #region Tests

        [TestMethod()]
        [Asynchronous]
        public void EntryTest()
        {
            User user = null;
            bool is_entryCompleted = false;
            _server.entryCompleted += 
                (object sender, SilverlightClient.SLWcfGeebaService.entryCompletedEventArgs e) =>
            {
                user = e.Result;
                is_entryCompleted = true;
            };
            _server.entryAsync();

            EnqueueConditional(() => is_entryCompleted);
            EnqueueCallback(() => Assert.IsNotNull(user));

            EnqueueTestComplete();
        }

        [TestMethod()]
        [Asynchronous]
        public void RegistrationTest()
        {
            Entry();

            // register...
            bool is_registerCompleted = false;
            bool registerRes = false;
            _server.registerCompleted +=
                 (object sender, SilverlightClient.SLWcfGeebaService.registerCompletedEventArgs e) =>
                 {
                     registerRes = e.Result;
                     is_registerCompleted = true;
                 };
            string username = TestUtils.GetNextUsername();
            string password = TestUtils.GetPassword();
            EnqueueCallback(() => _server.registerAsync(username, password));
            EnqueueConditional(() => is_registerCompleted);

            EnqueueCallback(() => Assert.IsTrue(registerRes));

            EnqueueTestComplete();
        }

        [TestMethod()]
        [Asynchronous]
        public void LoginTest()
        {
            Entry();
            RegisterNewMember();

            // login...
            bool is_loginCompleted = false;
            Member member = null;
            _server.loginCompleted +=
                    (object sender, SilverlightClient.SLWcfGeebaService.loginCompletedEventArgs e) =>
                    {
                        member = e.Result;
                        is_loginCompleted = true;
                    };
            EnqueueCallback(() => _server.loginAsync(_user, TestUtils.GetCurrentUsername(), TestUtils.GetPassword()));
            EnqueueConditional(() => is_loginCompleted);

            EnqueueCallback(() => Assert.IsNotNull(member));

            EnqueueTestComplete();
        }

        [TestMethod()]
        [Asynchronous]
        public void LogoutTest()
        {
            Entry();
            RegisterNewMember();
            LoginMember();

            // logout...
            LogoutCurrentMember();
            EnqueueCallback(() => Assert.IsNotNull(_user));

            EnqueueTestComplete();
        }

        [TestMethod()]
        [Asynchronous]
        public void GetSubForumsTest()
        {
            // get sub forums...
            int beforeCount = 0;
            GetSubForums();
            EnqueueCallback(() => beforeCount = _sfs.Count);

            // add sub forum as admin...
            AddNewSubForum();

            // get sub forums...
            GetSubForums();
            EnqueueCallback(() => Assert.IsTrue(_sfs != null && _sfs.Count == (beforeCount + 1)));

            EnqueueTestComplete();
        }

        [TestMethod()]
        [Asynchronous]
        public void AddSubForumsTest()
        {
            // get sub forums...
            int beforeCount = 0;
            GetSubForums();
            EnqueueCallback(() => beforeCount = _sfs.Count);

            // add sub forum as admin...
            AddNewSubForum();

            // get sub forums...
            GetSubForums();
            EnqueueCallback(() => 
            {
                Assert.IsTrue(_sfs != null && _sfs.Count == (beforeCount + 1));
                string topic = TestUtils.GetCurrentTopic();
                bool actual = false;
                foreach (GSubForum sf in _sfs)
                {
                    if (sf.topic.Equals(topic))
                    {
                        actual = true;
                        break;
                    }
                }
                Assert.IsTrue(actual);
            });

            EnqueueTestComplete();
        }

        [TestMethod()]
        [Asynchronous]
        public void RemoveSubForumTest()
        {
            // add sub forum as admin...
            AddNewSubForum();

            // remove sub forum
            bool is_removeSubForumCompleted = false;
            bool res = false;
            EnqueueCallback(() => _server.removeSubForumCompleted +=
                (object sender, SilverlightClient.SLWcfGeebaService.removeSubForumCompletedEventArgs e) =>
                {
                    if (e.Result)
                    {
                        res = true;
                    }
                    is_removeSubForumCompleted = true;
                });
            EnqueueCallback(() => _server.removeSubForumAsync(_admin, TestUtils.GetCurrentTopic()));
            EnqueueConditional(() => is_removeSubForumCompleted);
            EnqueueCallback(() => Assert.IsTrue(res));

            // get sub forums...
            GetSubForums();
            EnqueueCallback(() =>
            {
                Assert.IsNotNull(_sfs);
                string topic = TestUtils.GetCurrentTopic();
                bool actual = true;
                foreach (GSubForum sf in _sfs)
                {
                    if (sf.topic.Equals(topic))
                    {
                        actual = false;
                        break;
                    }
                }
                Assert.IsTrue(actual);
            });

            EnqueueTestComplete();
        }

        [TestMethod()]
        [Asynchronous]
        public void GetThreadsTest()
        {
            AddNewSubForum();

            Entry();
            RegisterNewMember();
            LoginMember();
            
            // get threads...
            GetThreadsFromCurrentSF();
            EnqueueCallback(() => Assert.IsTrue(_threads.Count == 0));
            
            PostNewThread();
            
            // get threads...
            GetThreadsFromCurrentSF();
            EnqueueCallback(() => Assert.IsTrue(_threads.Count == 1));
            
            EnqueueTestComplete();
        }

        [TestMethod()]
        [Asynchronous]
        public void PostThreadsTest()
        {
            AddNewSubForum();
            
            Entry();
            RegisterNewMember();
            LoginMember();

            // post new thread
            PostNewThread();

            EnqueueCallback(() => Assert.IsTrue(_thread._id > 0));

            EnqueueTestComplete();
        }

        [TestMethod()]
        [Asynchronous]
        public void PostCommentTest()
        {
            AddNewSubForum();

            Entry();
            RegisterNewMember();
            LoginMember();
            PostNewThread();

            // post new comment...
            PostNewComment();

            EnqueueCallback(() => Assert.IsTrue(_post._id > 0));

            EnqueueTestComplete();
        }

        [TestMethod()]
        [Asynchronous]
        public void RemoveThreadTest()
        {
            AddNewSubForum();

            Entry();
            RegisterNewMember();
            LoginMember();

            GetThreadsFromCurrentSF();
            EnqueueCallback(() => Assert.IsTrue(_threads.Count == 0));

            // post new thread
            PostNewThread();
            // post new comment...
            PostNewComment();

            EnqueueCallback(() => Assert.IsTrue(_thread._id > 0));

            // remove thread...
            bool is_removeThreadCompleted = false;
            bool res = false;
            EnqueueCallback(() => _server.removeThreadCompleted +=
                (object sender, SilverlightClient.SLWcfGeebaService.removeThreadCompletedEventArgs e) =>
                {
                    if (e.Result)
                    {
                        res = true;
                    }
                    is_removeThreadCompleted = true;
                });
            EnqueueCallback(() => _server.removeThreadAsync(_admin, TestUtils.GetCurrentTopic(), _thread._id));
            EnqueueConditional(() => is_removeThreadCompleted);
            EnqueueCallback(() => Assert.IsTrue(res));

            GetThreadsFromCurrentSF();
            EnqueueCallback(() => Assert.IsTrue(_threads.Count == 0));

            EnqueueTestComplete();
        }

        [TestMethod()]
        [Asynchronous]
        public void AddModeratorTest()
        {
            AddNewSubForum();

            Entry();
            RegisterNewMember();
            LoginMember();

            // add moderator should fail!
            AddModeratorToCurrentSF();
            EnqueueCallback(() => Assert.IsFalse(_addModRes));

            for (int i = 0; i < 5; i++)
            {
                PostNewThread();
            }

            // add moderator should succeed!
            AddModeratorToCurrentSF();
            EnqueueCallback(() => Assert.IsTrue(_addModRes));

            EnqueueTestComplete();
        }

        [TestMethod()]
        [Asynchronous]
        public void RemoveModeratorTest()
        {
            AddNewSubForum();
            Entry();
            RegisterNewMember();
            LoginMember();

            // add moderator
            for (int i = 0; i < 5; i++)
            {
                PostNewThread();
            }
            AddModeratorToCurrentSF();
            EnqueueCallback(() => Assert.IsTrue(_addModRes));

            // remove moderator
            bool is_removeModeratorCompleted = false;
            bool res = false;
            EnqueueCallback(() => _server.removeModeratorCompleted +=
                (object sender, SilverlightClient.SLWcfGeebaService.removeModeratorCompletedEventArgs e) =>
                {
                    if (e.Result)
                    {
                        res = true;
                    }
                    is_removeModeratorCompleted = true;
                });
            EnqueueCallback(() => _server.removeModeratorAsync(_admin, TestUtils.GetCurrentTopic(), _admin.username));
            EnqueueConditional(() => is_removeModeratorCompleted);

            EnqueueCallback(() => Assert.IsTrue(res));

            EnqueueTestComplete();
        }

        [TestMethod()]
        [Asynchronous]
        public void ReplaceModeratorTest()
        {
            AddNewSubForum();
            Entry();
            RegisterNewMember();
            LoginMember();

            for (int i = 0; i < 5; i++)
            {
                PostNewThread();
                //EnqueueCallback(() => Assert.IsTrue(_thread._id > 0));
            }

            // replace moderator
            bool is_replaceModeratorCompleted = false;
            bool res = false;
            EnqueueCallback(() => _server.replaceModeratorCompleted +=
                (object sender, SilverlightClient.SLWcfGeebaService.replaceModeratorCompletedEventArgs e) =>
                {
                    res = e.Result;
                    is_replaceModeratorCompleted = true;
                });
            EnqueueCallback(() => _server.replaceModeratorAsync(_admin, TestUtils.GetCurrentTopic(), _admin.username, _member.username));
            EnqueueConditional(() => is_replaceModeratorCompleted);

            EnqueueCallback(() => Assert.IsTrue(res));
            
            EnqueueTestComplete();
        }

        [TestMethod()]
        [Asynchronous]
        public void GetMemberThreadCountTest()
        {
            AddNewSubForum();
            Entry();
            RegisterNewMember();
            LoginMember();

            int before = 0;
            GetThreadsFromCurrentSFandMember();
            EnqueueCallback(() => before = _memberThreadCount);

            PostNewThread();
            GetThreadsFromCurrentSFandMember();
            EnqueueCallback(() => Assert.IsTrue((_memberThreadCount - before) == 1 ));

            PostNewThread();
            GetThreadsFromCurrentSFandMember();
            EnqueueCallback(() => Assert.IsTrue((_memberThreadCount - before) == 2));

            EnqueueTestComplete();
        }

        [TestMethod()]
        [Asynchronous]
        public void GetThreadCountTest()
        {
            AddNewSubForum();
         
            int before = 0;
            GetThreadCountFromCurrentSF();
            EnqueueCallback(() => before = _threadCount);
            
            Entry();
            RegisterNewMember();
            LoginMember();
            PostNewThread();
            GetThreadCountFromCurrentSF();
            EnqueueCallback(() => Assert.IsTrue((_threadCount - before) == 1));

            Entry();
            RegisterNewMember();
            LoginMember();
            PostNewThread();
            GetThreadCountFromCurrentSF();
            EnqueueCallback(() => Assert.IsTrue((_threadCount - before) == 2));

            EnqueueTestComplete();
        }

        [TestMethod()]
        [Asynchronous]
        public void EditContentTest()
        {
            AddNewSubForum();

            Entry();
            RegisterNewMember();
            LoginMember();
            PostNewThread();

            // edit content
            bool is_editContentCompleted = false;
            bool res = false;
            EnqueueCallback(() => _server.editContentCompleted +=
                (object sender, SilverlightClient.SLWcfGeebaService.editContentCompletedEventArgs e) =>
                {
                    res = e.Result;
                    is_editContentCompleted = true;
                });
            EnqueueCallback(() => _server.editContentAsync(_member, TestUtils.GetCurrentTopic(), _thread._id, TestUtils.GetNextContent()));
            EnqueueConditional(() => is_editContentCompleted);
            EnqueueCallback(() => Assert.IsTrue(res));

            EnqueueTestComplete();
        }

        [TestMethod()]
        [Asynchronous]
        public void BumpThreadTest()
        {
            int thr1_id = -1;

            AddNewSubForum();
            Entry();
            RegisterNewMember();
            LoginMember();
            PostNewThread();
            EnqueueCallback(() => thr1_id = _thread._id);
            PostNewThread();

            // edit content
            bool is_bumpCompleted = false;
            bool res = false;
            EnqueueCallback(() => _server.bumpThreadCompleted +=
                (object sender, SilverlightClient.SLWcfGeebaService.bumpThreadCompletedEventArgs e) =>
                {
                    res = e.Result;
                    is_bumpCompleted = true;
                });
            EnqueueCallback(() => _server.bumpThreadAsync(_member, TestUtils.GetCurrentTopic(), thr1_id));
            EnqueueConditional(() => is_bumpCompleted);
            EnqueueCallback(() => Assert.IsTrue(res));

            EnqueueTestComplete();
        }

        [TestMethod()]
        [Asynchronous]
        public void ChangePasswordTest()
        {
            Entry();
            RegisterNewMember();
            LoginMember();
            
            // change pass
            bool is_changePasswordCompleted = false;
            bool res = false;
            EnqueueCallback(() => _server.changePasswordCompleted +=
                (object sender, SilverlightClient.SLWcfGeebaService.changePasswordCompletedEventArgs e) =>
                {
                    res = e.Result;
                    is_changePasswordCompleted = true;
                });
            EnqueueCallback(() => _server.changePasswordAsync(_member, TestUtils.GetPassword(), TestUtils.GetNewPassword()));
            EnqueueConditional(() => is_changePasswordCompleted);
            EnqueueCallback(() => Assert.IsTrue(res));

            // logout
            LogoutCurrentMember();

            // try to login with old
            bool is_loginCompleted1 = false;
            EnqueueCallback(() => _server.loginCompleted +=
                    (object sender, SilverlightClient.SLWcfGeebaService.loginCompletedEventArgs e) =>
                    {
                        _member = e.Result;
                        is_loginCompleted1 = true;
                    });
            EnqueueCallback(() => _server.loginAsync(_user, TestUtils.GetCurrentUsername(), TestUtils.GetPassword()));
            EnqueueConditional(() => is_loginCompleted1);
            EnqueueCallback(() => Assert.IsNull(_member));

            // try to login with new
            bool is_loginCompleted2 = false;
            EnqueueCallback(() => _server.loginCompleted +=
                    (object sender, SilverlightClient.SLWcfGeebaService.loginCompletedEventArgs e) =>
                    {
                        _member = e.Result;
                        is_loginCompleted2 = true;
                    });
            EnqueueCallback(() => _server.loginAsync(_user, TestUtils.GetCurrentUsername(), TestUtils.GetNewPassword()));
            EnqueueConditional(() => is_loginCompleted2);
            EnqueueCallback(() => Assert.IsNotNull(_member));

            EnqueueTestComplete();
        }

        [TestMethod()]
        [Asynchronous]
        public void BanUserTest()
        {
            Entry();
            RegisterNewMember();
            LoginMember();

            AddNewSubForum();

            bool is_activeCompleted = false;
            bool res = false;
            EnqueueCallback(() => _server.SetActiveMemberCompleted +=
                    (object sender, SilverlightClient.SLWcfGeebaService.SetActiveMemberCompletedEventArgs e) =>
                    {
                        res = e.Result;
                        is_activeCompleted = true;
                    });
            EnqueueCallback(() => _server.SetActiveMemberAsync(_member, false));
            EnqueueConditional(() => is_activeCompleted);
            EnqueueCallback(() => Assert.IsTrue(res));

            PostNewThread();

            bool is_banCompleted = false;
            bool banRes = false;
            EnqueueCallback(() => _server.BanMemberCompleted +=
                    (object sender, SilverlightClient.SLWcfGeebaService.BanMemberCompletedEventArgs e) =>
                    {
                        banRes = e.Result;
                        is_banCompleted = true;
                    });
            EnqueueCallback(() => _server.BanMemberAsync(_admin, _member.username));
            EnqueueConditional(() => is_banCompleted);
            EnqueueCallback(() => Assert.IsTrue(banRes));

            EnqueueTestComplete();
        }

        [TestMethod()]
        [Asynchronous]
        public void SetUserInactiveTest()
        {
            Entry();
            RegisterNewMember();
            LoginMember();

            AddNewSubForum();

            bool is_activeCompleted = false;
            bool res = false;
            EnqueueCallback(() => _server.SetActiveMemberCompleted +=
                    (object sender, SilverlightClient.SLWcfGeebaService.SetActiveMemberCompletedEventArgs e) =>
                    {
                        res = e.Result;
                        is_activeCompleted = true;
                    });
            EnqueueCallback(() => _server.SetActiveMemberAsync(_member, false));
            EnqueueConditional(() => is_activeCompleted);
            EnqueueCallback(() => Assert.IsTrue(res));

            LogoutCurrentMember();
            LoginMember();

            EnqueueCallback(() => Assert.IsFalse(_member.isActive));

            EnqueueTestComplete();
        }

        [TestMethod()]
        [Asynchronous]
        public void RefinedInteractivityTest()
        {
            int threadID = 0;
            int postedThread1 = 0;
            int postedThread2 = 0;
            int postedThread3 = 0;

            string topic = "";
            // add subforum
            AddNewSubForum();
            EnqueueCallback(() => topic = _currentTopic);

            // register and login new member
            Entry();
            RegisterNewMember();
            LoginMember();

            Member member;
            EnqueueCallback(() => member = _member);

            // post new thread in the new subforum
            PostNewThread();
            EnqueueCallback(() =>
                {
                    threadID = _thread._id;
                    postedThread1 = (++threadID);
                    postedThread2 = (++threadID);
                    postedThread3 = (++threadID);
                });

            int count = 0;
            // subscribe
            EnqueueCallback(() => _server.UpdateReceived += new EventHandler<UpdateReceivedEventArgs>(
                (object sender, UpdateReceivedEventArgs e) =>
                {
                    bool shouldNotify = (e.message._id == postedThread2);
                    bool shouldNotNotify = (e.message._id == postedThread1) || (e.message._id == postedThread3);
                    if (e.IsNotification)
                    {
                        if (shouldNotNotify)
                        {
                            Assert.Fail();
                        }

                    }
                    else
                    {
                        if (shouldNotify)
                        {
                            Assert.Fail();
                        }
                    }
                    count++;
                }));
            Subscribe();

            // post new thread in the new subforum
            PostNewThread();
            EnqueueCallback(() => 
                postedThread1 = _thread._id );

            // register and login new member
            Entry();
            RegisterNewMember();
            LoginMember();

            Member member2;
            EnqueueCallback(() => member2 = _member);

            // post new thread in subforum 1 - should notify
            PostNewThread();
            EnqueueCallback(() => postedThread2 = _thread._id);

            // create new subforum
            string topic2 = "";
            // add subforum
            AddNewSubForum();
            EnqueueCallback(() => topic2 = _currentTopic);

            // member 2 post a new thread in subforum 2 - shouldn't notify
            PostNewThread();
            EnqueueCallback(() => 
                postedThread3 = _thread._id);

            EnqueueConditional(() => (count == 3));
            EnqueueTestComplete();
        }

        #endregion

        #region HelpMethods

        [Asynchronous]
        private void Entry()
        {
            bool is_entryCompleted = false;
            EnqueueCallback(() => _user = null);
            EnqueueCallback(() => _server.entryCompleted +=
                (object sender, SilverlightClient.SLWcfGeebaService.entryCompletedEventArgs e) =>
                {
                    Console.WriteLine("1");
                    if (e.Result == null)
                    {
                        Console.WriteLine("2");
                        throw new Exception("Could not enter!");
                    }
                    Console.WriteLine("3");
                    _user = e.Result;
                    Console.WriteLine("4");
                    is_entryCompleted = true;
                    Console.WriteLine("5");
                });
            EnqueueCallback(() => _server.entryAsync());
            EnqueueConditional(() => is_entryCompleted);
        }

        [Asynchronous]
        private void RegisterNewMember()
        {
            bool is_registerCompleted = false;
            EnqueueCallback(() => _server.registerCompleted +=
                 (object sender, SilverlightClient.SLWcfGeebaService.registerCompletedEventArgs e) =>
                 {
                     if (!e.Result)
                     {
                         throw new Exception("Could not register!");
                     }
                     is_registerCompleted = true;
                 });
            EnqueueCallback(() => _server.registerAsync(TestUtils.GetNextUsername(), TestUtils.GetPassword()));
            EnqueueConditional(() => is_registerCompleted);
        }

        [Asynchronous]
        private void LoginMember()
        {
            bool is_loginCompleted = false;
            EnqueueCallback(() => _server.loginCompleted +=
                    (object sender, SilverlightClient.SLWcfGeebaService.loginCompletedEventArgs e) =>
                    {
                        if (e.Result == null)
                        {
                            throw new Exception("Could not log-in!");
                        }
                        _member = e.Result;
                        is_loginCompleted = true;
                    });
            EnqueueCallback(() => _server.loginAsync(_user, TestUtils.GetCurrentUsername(), TestUtils.GetPassword()));
            EnqueueConditional(() => is_loginCompleted);
        }

        [Asynchronous]
        private void LogoutCurrentMember()
        {
            bool is_logoutCompleted = false;
            _server.logoutCompleted +=
                    (object sender, SilverlightClient.SLWcfGeebaService.logoutCompletedEventArgs e) =>
                    {
                        _user = e.Result;
                        is_logoutCompleted = true;
                    };
            EnqueueCallback(() => _server.logoutAsync(_member.username));
            EnqueueConditional(() => is_logoutCompleted);
            EnqueueTestComplete();
        }

        [Asynchronous]
        private void AddNewSubForum()
        {
            string topic = "";
            bool is_addSubForumCompleted = false;
            EnqueueCallback(() => _server.addSubForumCompleted +=
                (object sender, SilverlightClient.SLWcfGeebaService.addSubForumCompletedEventArgs e) =>
                {
                    //if (!e.Result)
                    //{
                    //    throw new Exception("Could not add sub forum!");
                    //}
                    is_addSubForumCompleted = true;
                });
            EnqueueCallback(() => _currentTopic = topic = TestUtils.GetNextTopic());
            EnqueueCallback(() => _server.addSubForumAsync(_admin, topic, TestUtils.GetAdminUsername()));
            EnqueueConditional(() => is_addSubForumCompleted);
        }

        [Asynchronous]
        private void GetSubForums()
        {
            bool is_getSubForumCompleted = false;
            EnqueueCallback(() => _server.getSubForumsCompleted +=
                (object sender, SilverlightClient.SLWcfGeebaService.getSubForumsCompletedEventArgs e) =>
                {
                    if (e.Result == null)
                    {
                        throw new Exception("Could not get Sub Forums!");
                    }
                    _sfs = new List<GSubForum>(e.Result);
                    is_getSubForumCompleted = true;
                });
            EnqueueCallback(() => _server.getSubForumsAsync());
            EnqueueConditional(() => is_getSubForumCompleted);
            EnqueueTestComplete();
        }

        [Asynchronous]
        private void GetThreadsFromCurrentSF()
        {
            bool is_getThreadsCompleted = false;
            EnqueueCallback(() => _server.getThreadsCompleted +=
                (object sender, SilverlightClient.SLWcfGeebaService.getThreadsCompletedEventArgs e) =>
                {
                    if (e.Result == null)
                    {
                        throw new Exception("Could not get threads!");
                    }
                    _threads = new List<GThread>(e.Result);
                    is_getThreadsCompleted = true;
                });
            EnqueueCallback(() => { GSubForum sf = new GSubForum(); sf.topic = _currentTopic; _server.getThreadsAsync(sf); } );
            EnqueueConditional(() => is_getThreadsCompleted);
            EnqueueTestComplete();
        }

        [Asynchronous]
        private void GetThreadsFromCurrentSFandMember()
        {
            bool is_getMemberThreadsCompleted = false;
            EnqueueCallback(() => _server.getMemberThreadCountCompleted +=
                (object sender, SilverlightClient.SLWcfGeebaService.getMemberThreadCountCompletedEventArgs e) =>
                {
                    //if (e.Result < 0)
                    //{
                    //    throw new Exception("Could not get member's thread count!");
                    //}
                    _memberThreadCount = e.Result;
                    is_getMemberThreadsCompleted = true;
                });
            EnqueueCallback(() => _server.getMemberThreadCountAsync(_admin, _member.username));
            EnqueueConditional(() => is_getMemberThreadsCompleted);
            EnqueueTestComplete();
        }
        
        [Asynchronous]
        private void GetThreadCountFromCurrentSF()
        {
            bool is_getThreadCountCompleted = false;
            EnqueueCallback(() => _server.getThreadCountCompleted +=
                (object sender, SilverlightClient.SLWcfGeebaService.getThreadCountCompletedEventArgs e) =>
                {
                    //if (e.Result < 0)
                    //{
                    //    throw new Exception("Could not get thread count!");
                    //}
                    _threadCount = e.Result;
                    is_getThreadCountCompleted = true;
                });
            EnqueueCallback(() => _server.getThreadCountAsync(_admin, TestUtils.GetCurrentTopic()));
            EnqueueConditional(() => is_getThreadCountCompleted);
            EnqueueTestComplete();
        }

        [Asynchronous]
        private void PostNewThread()
        {
            bool is_postThreadCompleted = false;
            int threadID = 0;
            EnqueueCallback(() => _server.publishCompleted +=
                    (object sender, SilverlightClient.SLWcfGeebaService.publishCompletedEventArgs e) =>
                    {
                        //if (e.Result <= 0)
                        //{
                        //    throw new Exception("Could not post thread!");
                        //}
                        threadID = e.Result;
                        is_postThreadCompleted = true;
                    });
            EnqueueCallback(() =>
            {
                _thread = new GThread();
                _thread._subject = TestUtils.GetNextSubject();
                _thread._content = TestUtils.GetNextContent();
                _thread._publisher = _member;
                _server.publishAsync(_member, TestUtils.GetCurrentTopic(), _thread);
            });
            EnqueueConditional(() => is_postThreadCompleted);
            EnqueueCallback(() => 
                _thread._id = threadID);
        }

        [Asynchronous]
        private void PostNewComment()
        {
            bool is_postCommentCompleted = false;
            int postID = 0;
            EnqueueCallback(() => _server.commentCompleted +=
                    (object sender, SilverlightClient.SLWcfGeebaService.commentCompletedEventArgs e) =>
                    {
                        //if (e.Result <= 0)
                        //{
                        //    throw new Exception("Could not post comment!");
                        //}
                        postID = e.Result;
                        is_postCommentCompleted = true;
                    });
            EnqueueCallback(() =>
            {
                _post = new GPost();
                _post._subject = TestUtils.GetNextSubject();
                _post._content = TestUtils.GetNextContent();
                _post._publisher = _member;
                _server.commentAsync(_member, _post, TestUtils.GetCurrentTopic(), _thread._id);
            });
            EnqueueConditional(() => is_postCommentCompleted);
            EnqueueCallback(() => _post._id = postID);
            //EnqueueTestComplete();
        }

        [Asynchronous]
        private void AddModeratorToCurrentSF()
        {
            bool is_addModeratorCompleted = false;
            EnqueueCallback(() => _server.addModeratorCompleted +=
                (object sender, SilverlightClient.SLWcfGeebaService.addModeratorCompletedEventArgs e) =>
                {
                    _addModRes = e.Result;
                    is_addModeratorCompleted = true;
                });
            EnqueueCallback(() => _server.addModeratorAsync(_admin, TestUtils.GetCurrentTopic(), _member.username));
            EnqueueConditional(() => is_addModeratorCompleted);
        }

        [Asynchronous]
        private void Subscribe()
        {
            bool is_subscribeCompleted = false;
            EnqueueCallback(() => _server.slSubscribeCompleted +=
                (object sender, System.ComponentModel.AsyncCompletedEventArgs e) =>
                {
                    if (e.Cancelled)
                    {
                        throw new Exception("Error Registering Interactive push notifications on server: " + e.Error);
                    }
                    is_subscribeCompleted = true;
                });
            EnqueueCallback(() => _server.slSubscribeAsync(_member.username));
            EnqueueConditional(() => is_subscribeCompleted);
        }

        #endregion

    }
}